#!/usr/bin/python
# -*- encoding: utf-8 -*-

"""
@File:      tc_libtevent_libtevent_func_008.py
@Time:      2024/04/23 14:51:50
@Author:    zhixin
@Version:   1.0
@Contact:   zx01468051@alibaba-inc.com
@License:   Mulan PSL v2
@Modify:    zhixin
"""

from common.basetest import LocalTest
import re

class Test(LocalTest):
    """
    See tc_libtevent_libtevent_func_008.yaml for details

    :avocado: tags=P2,noarch,local,fix
    """
    PARAM_DIC = {"pkg_name": "libtevent libtevent-devel libtalloc-devel gcc"}
    def setUp(self):
        super().setUp(self.PARAM_DIC)
        cmdline = """cat > tevent_test8.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include <tevent.h>
#include <pthread.h>

// 定时器事件回调函数
static void timer_event_handler(struct tevent_context *ev,
                                struct tevent_timer *te,
                                struct timeval current_time,
                                void *private_data)
{
    printf("线程 %lu: 定时器事件触发。\\n", (unsigned long)pthread_self());
    *(bool *)private_data = true;  // 设置标志以退出事件循环
}

// 线程函数，每个线程都会运行这个函数
void *thread_func(void *arg)
{
    // 每个线程创建自己的 tevent 上下文
    struct tevent_context *ev_ctx = tevent_context_init(NULL);
    if (ev_ctx == NULL) {
        fprintf(stderr, "线程 %lu: 无法初始化 tevent 上下文。\\n", (unsigned long)pthread_self());
        pthread_exit(NULL);
    }

    bool timer_fired = false;

    // 创建定时器事件
    struct timeval now, delta;
    now = tevent_timeval_current();
    delta = tevent_timeval_add(&now, 1, 0);  // 1秒后触发

    struct tevent_timer *timer;
    timer = tevent_add_timer(ev_ctx, NULL, delta, timer_event_handler, &timer_fired);
    if (timer == NULL) {
        fprintf(stderr, "线程 %lu: 创建定时器事件失败。\\n", (unsigned long)pthread_self());
        TALLOC_FREE(ev_ctx);
        pthread_exit(NULL);
    }

    // 运行事件循环，直到定时器事件触发
    while (!timer_fired) {
        if (tevent_loop_once(ev_ctx) != 0) {
            fprintf(stderr, "线程 %lu: 事件循环错误。\\n", (unsigned long)pthread_self());
            break;
        }
    }

    TALLOC_FREE(ev_ctx);
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t thread1, thread2;

    // 创建两个线程
    if(pthread_create(&thread1, NULL, thread_func, NULL) != 0) {
        fprintf(stderr, "无法创建线程 1\\n");
        return EXIT_FAILURE;
    }

    if(pthread_create(&thread2, NULL, thread_func, NULL) != 0) {
        fprintf(stderr, "无法创建线程 2\\n");
        pthread_cancel(thread1); // 取消先前创建的线程
        return EXIT_FAILURE;
    }

    // 等待两个线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("主线程: 所有线程已退出。\\n");
    return EXIT_SUCCESS;
}
EOF"""

        self.cmd(cmdline)
    
    def test(self):
        self.cmd('gcc -o tevent_test8 tevent_test8.c -ltevent -lpthread -ltalloc')
        code, tevent_result = self.cmd("./tevent_test8")
        self.assertIn('主线程: 所有线程已退出', tevent_result)

    def tearDown(self):
        super().tearDown(self.PARAM_DIC)
        self.cmd('rm -rf tevent_test8.c tevent_test8')
